<?php
// +----------------------------
// | Created by PhpStorm
// +----------------------------
// | Author: YnnSon
// +----------------------------
namespace app\api\service;

use app\api\controller\v1\Car as CarInterface;
use app\api\model\DrivingLicense as DrivingLicenseModel;
use app\api\model\Order as OrderModel;
use app\api\model\Subscribe as SubscribeModel;
use app\api\model\SubscribeCode;
use app\lib\exception\OrderException;
use think\Config;
use think\Db;
use think\Exception;
use think\Log;
use Yurun\Util\HttpRequest;

/**
 * 订单
 * Class Order
 * @package app\api\service
 */
class Order2
{
    // 前端传来的订单数据
    private $order;

    public function __construct($param)
    {
        $this->order = $param;
    }

    /**
     * @Desc 下单主方法
     * @return array
     */
    public function placeOrder()
    {
        Db::startTrans();
        try {
            // 检查库存量
            $this->checkSubscribeStock();
            // 生成订单数据
            $orderData = $this->generateOrderData();
            // 数据库新增一条订单记录
            // 返回订单ID
            $order = OrderModel::insertOrder($orderData);
            // 将返回的订单ID加到数组
            $this->order['order_id'] = $order['id'];
            // 预约数-1
            $this->reduceStocks($orderData['subscribe_id']);
            // 生成行驶证数据
            $drivingData = $this->generateDrivingData();
            // 修改行驶证信息
            $license = DrivingLicenseModel::updateLicenseFromOrder($drivingData);
            // 将生成的流水号加入预约信息
            $this->order['subscribe_info']['lsh'] = $orderData['lsh'];
            // 写入预约信息，结果为0代表写入错误，回滚
            $result = (new CarInterface())->writeInSubscribeInformation2($this->order['subscribe_info']);
            // {code: 1, msg: "提示信息"}
            if (0 == $result['code']) {
                throw new OrderException([
                    'code'      => 400,
                    'message'   => $result['msg'],
                    'errorCode' => 40001,
                ]);
            }
            Db::commit();
            // +------------------------------------------------------
            // | 收银系统接口
            // +------------------------------------------------------
            // $paymentOrderData = [
            //     'order_id'    => $orderData['order_sn'], // 预约平台订单号
            //     'yuyue_mid'   => $orderData['company_id'], // 检车站ID
            //     'goods_price' => $orderData['total_amount'], // 订单金额
            //     'add_time'    => $orderData['create_time'], // 订单创建时间
            //     'car_master'  => $license['user_name'], // 车主姓名
            //     'car_num'     => $license['license_number'], // 车牌号
            // ];
            // $this->sendOrderDataToPayment($paymentOrderData);
            // 调用微信统一下单接口
            // 将参数返回给前端
            $is_use = Db::name('base_subscribe_num')->where('company_id', '=', 0)->value('is_use');
            if ($is_use) {
                return ['order_id' => $order['id']];
            }
            // +------------------------------------------------------
            // | 收银系统接口
            // +------------------------------------------------------
            $paymentOrderData = [
                'order_id'    => $orderData['order_sn'], // 预约平台订单号
                'yuyue_mid'   => $orderData['company_id'], // 检车站ID
                'goods_price' => $orderData['total_amount'], // 订单金额
                'add_time'    => $orderData['create_time'], // 订单创建时间
                'car_master'  => $license['user_name'], // 车主姓名
                'car_num'     => $license['license_number'], // 车牌号
                'new_param'   => 1, //
            ];
            $this->sendOrderDataToPayment($paymentOrderData);
            return $this->unifiedOrder();
        } catch (Exception $e) {
            Db::rollback();
            Log::error($e);
            throw new OrderException([
                'code'      => 400,
                'message'   => $e->getMessage(),
                'errorCode' => 40001,
            ]);
        }
    }

    /**
     * @Desc 生成订单数据
     * @return array 订单数据
     */
    private function generateOrderData()
    {
        $order = $this->order;
        $order_sn = Config::get('setting.order_prefix') . date('YmdHis') . random_int(100000, 999999); // 订单号
        $this->order['order_sn'] = $order_sn;
        $this->order['total_amount'] = $order['goods_price'];
        $open_id = Token::getOpenidFromCache();
        $user_weixin_id = Token::getUidFromCache();
        // 生成流水号
        $lsh = Config::get('subscribe.babh') . date('ymd') . randomStr(5);
        $orderData = [
            'order_sn'           => $order_sn,
            'open_id'            => $open_id,
            'company_id'         => $order['company_id'],
            'driving_license_id' => $order['driving_license_id'],
            'user_weixin_id'     => $user_weixin_id,
            'mobile'             => $order['mobile'],
            'subscribe_id'       => $order['subscribe_id'],
            'subscribe_date'     => strtotime($order['subscribe_date']),
            'goods_id'           => $order['goods_id'],
            'goods_name'         => $order['goods_name'],
            'goods_price'        => $order['goods_price'],
            'order_amount'       => $order['goods_price'], // 所有商品数量相加
            'total_amount'       => $this->order['total_amount'], // 若添加优惠券功能，则减去优惠金额
            'vehicle_id'         => $order['vehicle_id'],
            'license_type'       => $order['vehicle_id'],
            'vehicle_name'       => $order['vehicle_name'],
            'user_note'          => $order['user_note'],
            'coupon_id'          => $order['coupon_id'],
            'zt'                 => 0,
            'lsh'                => $lsh,
        ];
        if (array_key_exists('address', $order)) {
            $orderData['address'] = $order['address'];
        }
        $today = date('Y-m-d');
        $orderData['subscribe_code'] = SubscribeCode::getAndUpdateData($order['company_id'], $today);
        return $orderData;
    }

    /**
     * @Desc 生成行驶证数据
     * @return array 行驶证数据
     */
    private function generateDrivingData()
    {
        $driving = $this->order;
        return [
            'id'                 => $this->order['driving_license_id'],
            'license_nature'     => $driving['license_nature'],
            'vehicle_brand'      => $driving['vehicle_brand'],
            'license_grant_date' => $driving['license_grant_date'],
        ];
    }

    /**
     * @Desc 调用微信统一下单接口
     * @return array 要返回给前端的数据
     */
    private function unifiedOrder()
    {
        $order = [
            'order_id'     => $this->order['order_id'],
            'order_sn'     => $this->order['order_sn'],
            'total_amount' => $this->order['total_amount'],
        ];
        $pay = new Pay($order);
        return $pay->pay();
    }

    /**
     * @Desc 检测剩余预约数量
     * @return bool
     */
    private function checkSubscribeStock()
    {
        // 首先请求车管接口查询该时间段所有车辆预约状态, 确保两端信息同步
        // (new \app\api\controller\v1\Car())->checkAllSubscribeStatus();
        if ($subscribe_id = $this->order['subscribe_id']) {
            // 查询该时间段预约数, 有剩余才能预约
            $num = SubscribeModel::getNumById($subscribe_id, $this->order['company_id'], $this->order['vehicle_id']);
            if (0 >= $num) {
                throw new OrderException([
                    'code'      => 400,
                    'message'   => '该时间段已满，请选择其他时间',
                    'errorCode' => 40005,
                ]);
            }
        }
        return true;
    }

    /**
     * @Desc 预约数-1
     *
     * @param $subscribe_id
     */
    private function reduceStocks($subscribe_id)
    {
        if (45 == $this->order['company_id'] && 1 == $this->order['vehicle_id']) {
            (new SubscribeModel())->where('id', '=', $subscribe_id)->setDec('num_gas');
        } elseif (45 == $this->order['company_id'] && (2 == $this->order['vehicle_id'] || 3 == $this->order['vehicle_id'])) {
            (new SubscribeModel())->where('id', '=', $subscribe_id)->setDec('num_diesel');
        } else {
            (new SubscribeModel())->where('id', '=', $subscribe_id)->setDec('num');
        }
    }

    /**
     * @Desc 向收银系统发送订单数据
     *
     * @param array $data 要发送的数据
     *
     * @return mixed
     */
    private function sendOrderDataToPayment($data)
    {
        $url = Config::get('setting.add_order_url'); // 生产环境接口
        // $url = Config::get('setting.test_add_order_url'); // 开发环境接口
        return (new HttpRequest())->post($url, $data)->json(true);
    }
}